package control

import (
	"github.com/hyperledger/fabric/core/chaincode/shim"
	"github.com/hyperledger/fabric/protos/peer"
	"encoding/json"
	"fmt"
	"canliancontract/log"
	"canliancontract/common"
	"canliancontract/module"
	"strings"
	"net/http"
	"io/ioutil"
)

func substring(source string, start int, end int) string {
	var r = []rune(source)
	length := len(r)

	if start < 0 || end > length || start > end {
		return ""
	}

	if start == 0 && end == length {
		return source
	}

	return string(r[start : end])
}

func (t *CanlianTrace) QueryTransferByType(stub shim.ChaincodeStubInterface, args []string) peer.Response {
	log.Logger.Info("################# 查询各个交易类型 详情1 ############################")
	if len(args) == 1 {
		var param module.QueryList
		err := json.Unmarshal([]byte(args[0]), &param)
		if err != nil {
			log.Logger.Error("args json unmarshal err")
			return shim.Error("序列化出错")
		}

		log.Logger.Info(param.Type)

		if param.Type != int(1) && param.Type != int(2) {
			log.Logger.Error("只能查询康复机构和补贴申请，参数错误。")
			return shim.Error("只能查询康复机构和补贴申请，参数错误。")
		}

		queryString := fmt.Sprintf("{\"selector\":{\"type\": {\"$eq\": %d}},\"sort\":[{\"operate_time\":\"desc\"}],\"limit\":\"%d\", \"skip\":%d}", param.Type ,param.Limit, param.Skip)
		log.Logger.Info(queryString)
		queryResults, err := stub.GetQueryResult(queryString)

		if err != nil {
			//log.Logger.Info("1111111111111")
			return shim.Error(err.Error())
		}
		//log.Logger.Info("222222222222")
		defer queryResults.Close()
		results := make([]map[string]interface{}, 0)
		index := 0
		count := 0
		for queryResults.HasNext() {
			result, err := queryResults.Next()
			if err != nil {
				//log.Logger.Info("33333333333333333")
				return shim.Error(err.Error())
			}
			value := make(map[string]interface{})
			err = json.Unmarshal(result.Value, &value)
			if err != nil {
				return shim.Error(err.Error())
			}

			if index < param.Skip {
				index++
				continue
			}
			count++

			if param.Type == int(2) {
				log.Logger.Info("++++++隐藏身份证号和姓名================")
				disability_certificate_no := value["disability_certificate_no"].(string)
				slice := strings.Split(disability_certificate_no, "")
				new_disability_certificate_no := strings.Join(slice[0:4],"") + "***" + strings.Join(slice[len(slice)-4:],"")
				value["disability_certificate_no"] = new_disability_certificate_no

				name := value["name"].(string)
				//slice_name := strings.Split(name, "")
				//newName := strings.Join(slice_name[0:0], "")+"**"
				value["name"] = substring(name, 0, 1) + "**"

				log.Logger.Info("*************************************",value)
			}
			if param.Type == int(1) {
				contact := value["contact"].(string)
				value["contact"] = substring(contact,0,1) + "**"

				contact_tel := value["contact_tel"].(string)
				value["contact_tel"] = substring(contact_tel,0,3) + "**"
			}

			results = append(results, value)
			if count >= param.Limit{
				break
			}
		}
		//log.Logger.Info("44444444444444")
		resultsJSON, err := json.Marshal(results)
		if err != nil {
			return shim.Error(err.Error())
		}
		return shim.Success(resultsJSON)
	} else {
		log.Logger.Error("QueryTransferByType:参数不对，请确认参数信息。")
		return shim.Error("参数不对，请确认参数信息。")
	}
}

/**查询所有交易详情**/
func (t *CanlianTrace) QueryAllTransfer(stub shim.ChaincodeStubInterface, args []string) peer.Response {

	log.Logger.Info("################# 查询所有交易  ############################")
	if len(args) == 1 {
		var param module.QueryList
		err := json.Unmarshal([]byte(args[0]), &param)
		if err != nil {
			log.Logger.Error("args json unmarshal err")
			return shim.Error("序列化出错")
		}
		if param.Type == 0 {
			//timedata := "2011-12-12 12:03:04"
			//str := `{"selector":{"time": {"$gt":"2011-12-09 12:12:12"}},"sort":[{"time": "desc"}],"limit": "10","skip": 10}`
			queryString := fmt.Sprintf("{\"selector\": {\"type\": {\"$gte\": 0}}, \"sort\":[{\"operate_time\":\"desc\"}],\"limit\": \"%d\", \"skip\": %d}", param.Limit, param.Skip)
			log.Logger.Info(queryString)
			queryResults, err := stub.GetQueryResult(queryString)
			if err != nil {
				return shim.Error(err.Error())
			}
			defer queryResults.Close()
			results := make([]map[string]interface{}, 0)
			index := 0
			count := 0
			for queryResults.HasNext() {
				result, err := queryResults.Next()
				if err != nil {
					return shim.Error(err.Error())
				}
				value := make(map[string]interface{})
				err = json.Unmarshal(result.Value, &value)
				if err != nil {
					return shim.Error(err.Error())
				}
				if index < param.Skip {
					index++
					continue
				}
				count++
				txList := make(map[string]interface{})
				txList["time"] = value["operate_time"]
				txList["hash"] = value["hash"]
				txList["type"] = value["type"]
				results = append(results, txList)
				if count >= param.Limit{
					break
				}
			}


			resultsJSON, err := json.Marshal(results)
			if err != nil {
				return shim.Error(err.Error())
			}
			return shim.Success(resultsJSON)
		} else {
			log.Logger.Error("参数错误。")
			return shim.Error("参数错误。")
		}
	} else {
		log.Logger.Error("QueryTransferByType:参数不对，请确认参数信息。")
		return shim.Error("参数不对，请确认参数信息。")
	}
}

/**交易数，显示所有的交易简要信息**/
//func (t *CanlianTrace) QueryTXList(stub shim.ChaincodeStubInterface, args []string) peer.Response {
//	log.Logger.Info("##############调用 QueryTXList 接口开始###############")
//
//	historys, err := stub.GetHistoryForKey(common.TX_LIST)
//	if err != nil {
//		log.Logger.Error("QueryTXList err:" + err.Error())
//		return shim.Error(err.Error())
//	}
//	defer historys.Close()
//	rows := make([]interface{}, 0)
//	for historys.HasNext() {
//		result, err := historys.Next()
//		if err != nil {
//			return shim.Error(err.Error())
//		}
//		var record interface{}
//		err = json.Unmarshal(result.Value, &record)
//		if err != nil {
//			return shim.Error(err.Error())
//		}
//		rows = append(rows, record)
//	}
//	resultsJSON, err := json.Marshal(rows)
//	if err != nil {
//		return shim.Error(err.Error())
//	}
//	return shim.Success(resultsJSON)
//}

/**查询总的交易数**/
func (t *CanlianTrace) QueryTXCount(stub shim.ChaincodeStubInterface, args []string) peer.Response {
	countByts, err := stub.GetState(common.TX_COUNT + common.ULINE + common.TX_NUMBER)
	fmt.Println(countByts)
	if err != nil {
		fmt.Println(err.Error())
		return shim.Error(err.Error())
	}
	return shim.Success(countByts)
}

/**地图查询城市残疾人数据**/
/*func (t *CanlianTrace) QueryCityDisabilityNum(stub shim.ChaincodeStubInterface, args []string) peer.Response {
	countByts, err := stub.GetState(common.CITY_DISABILITY_NUM)
	log.Logger.Info("地图数据城市残疾人数据统计")
	fmt.Println(countByts)
	log.Logger.Info("地图数据城市残疾人数据统计")
	if err != nil {
		log.Logger.Info("地图数据城市残疾人数据统计")
		fmt.Println(err.Error())
		return shim.Error(err.Error())

	}
	log.Logger.Info("地图数据城市残疾人数据统计")
	return shim.Success(countByts)
}
*/
/**地图查询城市康复救助补贴数目**/
/*func (t *CanlianTrace) QueryCitySubsidyNum(stub shim.ChaincodeStubInterface, args []string) peer.Response {
	countByts, err := stub.GetState(common.CITY_SUBSIDY_NUM)
	fmt.Println(countByts)
	if err != nil {
		fmt.Println(err.Error())
		return shim.Error(err.Error())
	}
	return shim.Success(countByts)
}
*/
/**地图查询城市康复机构数据**/
/*func (t *CanlianTrace) QueryCityRehabilitationNum(stub shim.ChaincodeStubInterface, args []string) peer.Response {
	countByts, err := stub.GetState(common.CITY_REHABILITATION_NUM)
	fmt.Println(countByts)
	if err != nil {
		fmt.Println(err.Error())
		return shim.Error(err.Error())
	}
	return shim.Success(countByts)
}*/

/**查询残疾人信息交易数**/
/*func (t *CanlianTrace) QueryDisabilityTXCount(stub shim.ChaincodeStubInterface, args []string) peer.Response {
	countByts, err := stub.GetState(common.TX_COUNT + common.ULINE + common.DISABILITY)
	fmt.Println(countByts)
	if err != nil {
		fmt.Println(err.Error())
		return shim.Error(err.Error())
	}
	return shim.Success(countByts)
}
*/
/**查询康复机构交易数**/
/*func (t *CanlianTrace) QueryRehabilitationTXCount(stub shim.ChaincodeStubInterface, args []string) peer.Response {
	countByts, err := stub.GetState(common.TX_COUNT + common.ULINE + common.REHABILITATION)
	fmt.Println(countByts)
	if err != nil {
		fmt.Println(err.Error())
		return shim.Error(err.Error())
	}
	return shim.Success(countByts)
}
*/
/**查询补贴申请交易数**/
/*func (t *CanlianTrace) QuerySubsidyTXCount(stub shim.ChaincodeStubInterface, args []string) peer.Response {
	countByts, err := stub.GetState(common.TX_COUNT + common.ULINE + common.SUBSIDY)
	fmt.Println(countByts)
	if err != nil {
		fmt.Println(err.Error())
		return shim.Error(err.Error())
	}
	return shim.Success(countByts)
}*/

/**跟据交易hash查询交易详情**/
func (t *CanlianTrace) QueryTXByHash(stub shim.ChaincodeStubInterface, args []string) peer.Response {
	log.Logger.Info("##############调用QueryTRANSFERHistoryproduct接口开始###############")
	if len(args) < 1 {
		return shim.Error("参数不对，请核实参数信息。" )
	}
	var param module.QueryParam
	err := json.Unmarshal([]byte(args[0]), &param)
	if err != nil {
		log.Logger.Error("QueryTransferHistoryByProduct:err:" + err.Error())
		return shim.Error("err:" + err.Error())
	}

	countByts, err := stub.GetState(common.TXHASH + common.ULINE + param.Hash)
	fmt.Println(countByts)
	if err != nil {
		fmt.Println(err.Error())
		return shim.Error(err.Error())
	}

	//解析隐藏交易
	result := make(map[string]interface{})
	json.Unmarshal(countByts, &result)

	if result["type"] == float64(0) {
		//name
		name := result["name"].(string)
		result["name"] = substring(name, 0, 1) + "**"

		//证件编号
		disability_certificate_no := result["disability_certificate_no"].(string)
		slice := strings.Split(disability_certificate_no, "")
		new_disability_certificate_no := strings.Join(slice[0:4],"") + "***" + strings.Join(slice[len(slice)-4:],"")
		result["disability_certificate_no"] = new_disability_certificate_no

		result["address"] = "***"

		guardian_name := result["guardian_name"].(string)
		result["guardian_name"] = substring(guardian_name, 0, 1) + "**"

		contact_tel := result["contact_tel"].(string)
		result["contact_tel"] = substring(contact_tel, 0, 3) + "**"
	}

	if result["type"] == float64(1) {
		legal_person := result["legal_person"].(string)
		result["legal_person"] = substring(legal_person, 0, 1) + "**"

		contact := result["contact"].(string)
		result["contact"] = substring(contact, 0, 1) + "**"

		contact_tel := result["contact_tel"].(string)
		result["contact_tel"] = substring(contact_tel, 0, 3) + "**"
	}

	if result["type"] == float64(2) {
		name := result["name"].(string)
		result["name"] = substring(name, 0, 1) + "**"

		disability_certificate_no := result["disability_certificate_no"].(string)
		slice := strings.Split(disability_certificate_no, "")
		new_disability_certificate_no := strings.Join(slice[0:4],"") + "***" + strings.Join(slice[len(slice)-4:],"")
		result["disability_certificate_no"] = new_disability_certificate_no

		guardian_name := result["guardian_name"].(string)
		result["guardian_name"] = substring(guardian_name, 0, 1) + "**"

		contact_tel := result["contact_tel"].(string)
		result["contact_tel"] = substring(contact_tel, 0, 3) + "**"

	}
	log.Logger.Info("name:","type:",result["name"],result["type"])

	//disability_certificate_no := value["disability_certificate_no"].(string)
	//slice := strings.Split(disability_certificate_no, "")
	//new_disability_certificate_no := strings.Join(slice[0:3],"") + "***" + strings.Join(slice[len(slice)-4:],"")
	//value["disability_certificate_no"] = new_disability_certificate_no
	//
	//name := value["name"].(string)
	////slice_name := strings.Split(name, "")
	////newName := strings.Join(slice_name[0:0], "")+"**"
	//value["name"] = substring(name, 0, 1) + "**"

	newByte, err := json.Marshal(result)
	if err != nil {
		log.Logger.Error("Marshal error")
	}

	return shim.Success(newByte)

	//return service.QueryTransferHistoryByProduct(stub, param)
}

//func (t *CanlianTrace) QueryNum(stub shim.ChaincodeStubInterface, args []string) peer.Response {
//	countByts, err := stub.GetState(common.COUNT_ALL_NUMBER)
//	fmt.Println(countByts)
//	if err != nil {
//		fmt.Println(err.Error())
//		return shim.Error(err.Error())
//	}
//	return shim.Success(countByts)
//}

func (t *CanlianTrace) QueryNum(stub shim.ChaincodeStubInterface, args []string) peer.Response {
	url := "http://42.51.64.58/statstic/get"
	resp, err := http.Get(url)
	if err != nil {
		log.Logger.Error("http request error")
		return shim.Error("http request error")
	}
	defer resp.Body.Close()
	
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Logger.Error("read resp err")
		return shim.Error("read resp err")
	}

	return shim.Success(body)
}
